package com.gxuwz.medical.domain.user;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.gxuwz.medical.database.DBUtil;
import com.gxuwz.medical.domain.role.Role;
import com.gxuwz.medical.exception.UserNotFoundException;

/**
 * 用户管理模块类
 */
public class User {
	//用户编号
	private String userId; 
	//密码
	private String password; 
	//用户名
	private String fullName;
	//状态
	private String status; 
	// 行政区域编号
	private String agencode; 
     
	private Set<Role> roles;

	public User() {

	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public void load(String userId) throws SQLException {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = DBUtil.getConn();
			pstmt = conn.prepareStatement("select * from user where userId=?");
			int index = 1;
			pstmt.setString(index, userId);
			rs = pstmt.executeQuery();
			if (rs != null && rs.next()) {
				this.userId = rs.getString("userId");
				this.password = rs.getString("password");
				this.fullName = rs.getString("fullName");
				this.status = rs.getString("status");
				this.agencode = rs.getString("agencode");

			}

		} catch (SQLException e) {
			throw new SQLException("User with id " + userId
					+ " could not be loaded from the database.");
		} finally {
			DBUtil.close(rs, pstmt, conn);
		}
	}

	public User(String userId, String password, String fullName, String status,
			String agencode) {
		super();
		this.userId = userId;
		this.password = password;
		this.fullName = fullName;
		this.status = status;
		this.agencode = agencode;
	}

	public String getAgencode() {
		return agencode;
	}

	public void setAgencode(String agencode) {
		this.agencode = agencode;
	}

	public void delUser(String userId) throws SQLException {
		Connection conn = null;
		this.userId = userId;
		try {
			conn = DBUtil.getConn();
			conn.setAutoCommit(false);
			deleteFromDB(conn);
			unbindRole(conn);
			conn.commit();
		} catch (SQLException e) {
			conn.rollback();
			throw e;
		} finally {
			DBUtil.close(conn);
		}
	}

	private void deleteFromDB(Connection conn) throws SQLException {

		PreparedStatement pstmt = null;
		try {
			StringBuffer sqlBuff = new StringBuffer(
					"delete from user where userId=?");
			pstmt = conn.prepareStatement(sqlBuff.toString());
			pstmt.setString(1, this.userId);

			pstmt.executeUpdate();
		} catch (SQLException e) {
			throw new SQLException("Failed to delete record from table !", e);
		} finally {
			DBUtil.close(pstmt);
		}

	}

	public User(String userId, String password) throws UserNotFoundException,
			SQLException {

		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = DBUtil.getConn();
			pstmt = conn
					.prepareStatement("select * from user where userId=? and password=?");
			int index = 1;
			pstmt.setString(index++, userId);
			pstmt.setString(index, password);
			rs = pstmt.executeQuery();
			if (rs != null && rs.next()) {
				this.fullName = rs.getString("fullName");
				this.password = rs.getString("password");
				this.userId = rs.getString("userId");
				this.agencode = rs.getString("agencode");
			} else {
				throw new UserNotFoundException("User with id " + userId
						+ " could not be loaded from the database.");
			}
		} catch (SQLException e) {

			throw new UserNotFoundException("User with id " + userId
					+ " could not be loaded from the database.");

		} finally {
			DBUtil.close(rs, pstmt, conn);
		}
	}

	public void addUser(String[] roleIds) throws SQLException {
		Connection conn = null;
		try {
			//获得连接
			conn = DBUtil.getConn();
			//开启手动提交事务
			conn.setAutoCommit(false);
			//保存到数据库
			saveToDB(conn);
			if (roleIds != null) {
				for (String roleId : roleIds) {
					bindRole(conn, roleId);
				}
			}
			conn.commit();

		} catch (SQLException e) {
			conn.rollback();
			throw e;
		} finally {
			DBUtil.close(conn);
		}
	}

	private void bindRole(Connection conn, String roleId) throws SQLException {
		PreparedStatement pstmt = null;
		try {
			StringBuffer sqlBuff = new StringBuffer(
					"insert into user_role(userId,roleId)");
			sqlBuff.append("values(?,?)");
			pstmt = conn.prepareStatement(sqlBuff.toString());
			pstmt.setString(1, this.userId);
			pstmt.setString(2, roleId);
			pstmt.executeUpdate();
		} catch (SQLException e) {
			throw new SQLException("Failed to bind to Role!", e);
		} finally {
			DBUtil.close(pstmt);
		}
	}

	public void editUser(String[] roleIds) throws SQLException {
		Connection conn = null;
		try {
			conn = DBUtil.getConn();
			conn.setAutoCommit(false);
			eidtToDB(conn);
			unbindRole(conn);
			for (String roleId : roleIds) {
				bindRole(conn, roleId);
			}
			conn.commit();
		} catch (SQLException e) {
			conn.rollback();
			throw e;
		} finally {
			DBUtil.close(conn);
		}
	}

	private void unbindRole(Connection conn) throws SQLException {

		PreparedStatement pstmt = null;
		try {
			StringBuffer sqlBuff = new StringBuffer(
					"delete from user_role where userId=?");
			pstmt = conn.prepareStatement(sqlBuff.toString());
			pstmt.setString(1, this.userId);
			pstmt.executeUpdate();
		} catch (SQLException e) {
			throw new SQLException("Failed to unbind to Role !", e);
		} finally {
			DBUtil.close(pstmt);
		}

	}

	private void eidtToDB(Connection conn) throws SQLException {

		PreparedStatement pstmt = null;
		try {
			StringBuffer sqlBuff = new StringBuffer(
					"update user t set t.fullName=?,t.password=?,agencode=?,status=?  where t.userId=?");
			pstmt = conn.prepareStatement(sqlBuff.toString());
			pstmt.setString(1, this.fullName);
			pstmt.setString(2, this.password);
			pstmt.setString(3, this.agencode);
			pstmt.setString(4, this.status);
			pstmt.setString(5, this.userId);
			//执行修改sql语句
			pstmt.executeUpdate();
		} catch (SQLException e) {
			throw new SQLException("Failed to update user  !", e);
		} finally {
			DBUtil.close(pstmt);
		}
	}

	private void saveToDB(Connection conn) throws SQLException {

		PreparedStatement pstmt = null;
		try {
			StringBuffer sqlBuff = new StringBuffer(); //创建一个新的StringBuffer实例 sqlBuff
			sqlBuff.append("insert into user(userId,fullName,password,agencode,status)");//字符串拼接
			sqlBuff.append("values(?,?,?,?,?)");
			pstmt = conn.prepareStatement(sqlBuff.toString());
			pstmt.setString(1, this.userId); //给第一个?设置一个字符串类型的值为userId (索引，值)
			pstmt.setString(2, this.fullName);
			pstmt.setString(3, this.password);
			pstmt.setString(4, this.agencode);
			pstmt.setString(5, this.status);
			//执行sql语句
			pstmt.executeUpdate();
		} catch (SQLException e) {
			throw e;
		} finally {
			//关闭连接
			DBUtil.close(pstmt);
		}
	}

	public User(String userId) throws UserNotFoundException, SQLException {

		load(userId);
	}

	public String getUserId() {
		return userId;
	}

	public void setUserid(String userId) {
		this.userId = userId;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getFullName() {
		return fullName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}

	private List<String> getRoleIds() throws SQLException {

		List<String> roleIds = new ArrayList<String>();
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = DBUtil.getConn();
			pstmt = conn
					.prepareStatement("select roleId from user_role where userId=?");
			int index = 1;
			pstmt.setString(index++, userId);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				roleIds.add(rs.getString(1));
			}
		} catch (SQLException e) {

			e.printStackTrace();

		} finally {
			DBUtil.close(rs, pstmt, conn);
		}
		return roleIds;
	}

	public Set<Role> getRoles() {
		try {
			if (roles == null) {
				roles = new HashSet<Role>();
				List<String> roleIds = getRoleIds();
				for (String roleId : roleIds) {
					Role role = new Role(roleId);
					roles.add(role);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return roles;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

}
